关于C++编写com和调用com组件的小例子以及个人所犯错误见解

您所在的位置:网站首页 vs com组件 关于C++编写com和调用com组件的小例子以及个人所犯错误见解

关于C++编写com和调用com组件的小例子以及个人所犯错误见解

2023-08-24 21:19| 来源: 网络整理| 查看: 265

最近在完成研究生课程面向对象方法的第一次作业编写一个com:

注意注意!!!如果是C#等边写的跨语言的com组件调用,建议在import的时候的步骤,采用导入com组件的.tlb文件,也就是import进去的是tlb文件,不然如果导入dll会报错

 

环境Visual Studio 2015

一、构造COM组件,项目名称为ComZhh,过程

进入VS,选择左上角的文件,点击新建项目->Visual C++->ATL->ATL项目

注意在下一步中勾选支持com+1.0

接着你讲看到项目下有两个目录

不要着急,你只需要关注ATLProject1即可。然后,你需要开始定义组件内部的类,也就是你的组件的功能部分,我只讲解定义一个功能的内容。在你的项目下,右键添加->添加类->ATL->ATL简单对象

在此后注意下图中的ProgID这一栏,填写完类名之后你需要给你的组件一个名称,它是唯一的,在C++d额客户程序中查找你所定义的类的时候至关重要,

我定义的名称为hello.important,要着重强调。然后点击完成即可,然后注意要找到你的解决方案资源管理器中的类视图!注意 是类视图。

在类视图中可以看到刚刚定义的hello类,但是名称和我们实际定义的不太一样,变成了Chello和Ihello,不过不用担心,你不需要在意,你只需要在Ihello也就是你的类的接口类上右键,->添加->添加方法,定义你所需要的函数

我们可以看到out、retval那两个地方是灰色的,并且在我所看到的教程中大多数人没有提到如何使用,因为out模块代表的是函数的返回值,如果不定义out特性的参数,则无法获得调用函数所获得的返回值。因此我们需要定义一个指针类型的参数,

当你选择了指针类型的参数类型后,out和retval会自动变成可选的,此时在out上打勾,表明zheli这个参数是用来获取返回值的。

也就是现在这个样子,此时你可以看到你的类和接口类中同时都存在了hahaha函数的定义

此后开始实现你的方法

Chello就是你所定义的hello,只是说在头文件中系统自动定义成了Chello类而已 ,并不影响理解和使用。return S_OK是com组件中任意函数的返回值,【out】特性才是返回值,这也可以保证一个函数可以有多个输出值

此时com组件就定义完成了,点击生成->生成解决方案

此时可以在代码的项目目录中看到dll 文件,使用管理员运行cmd,进入dll所在目录执行

regsvr32   “ATLProject1.dll” 将dll添加到注册表中即可。

下面介绍如何通过C++调用com组件

首先新建一个win32的控制台应用程序

直接点击完成即可,然后复制你要调用的dll文件到vs的目录下面,因为如果不这么做vs中c++的import会提示无法打开源文件(.tlh)如下:

然后进入ConsoleApplication1.cpp构建调用函数

此时会显示C1083的错误,注意在这里我犯了错误,因为dll添加进项目的步骤应该是先将dll复制到项目文件夹下然后再vs中的项目中点击添加->添加现有项,选择你将要使用的dll文件,点击添加。

当你这么执行了添加操作之后,仍然会提示无法打开.tlh文件,这可能是vs的小bug?不要着急,接下来直接点击 生成->清理解决方案 然后点击 生成->重新生成解决方案,你会发现此时错误以及程序中import下的红线神奇的消失了,此时import就已经成功了,你可以开始尽情调用了。噢 对 应该是#import"ComZhh.dll" no_namespace ,后面的no_namespace应该也挺重要的,虽然还不是太懂,毕竟刚刚接触QAQ。

 

int main() { CoInitialize(NULL); CLSID clsid; CLSIDFromProgID(OLESTR("hello.important"), &clsid);//!!!!!这个是你创建ATL的时候定义的 //progid!不要被网上的“dll名称+接口”误导!!!这个地方只要写错不管怎么调试都无法调用dll CComPtr pHello;//智能指针 pHello.CoCreateInstance(clsid); Long* result; pHello->hahaha(&result); pHello.Release();//小心哦!!请看最后的“注意” CoUninitialize(); return 0; }

填写完成代码之后直接调试就ok啦

如果是bstr*的result有如下的操作需要注意:

BSTR result; pShoot->showShoot(&result); char* resultConvert=_com_util::ConvertBSTRToString(result); std::cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3